package pfc.view.view.formularios;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.IOException;
import java.util.Vector;

import javax.imageio.ImageIO;
import javax.media.Buffer;
import javax.media.CaptureDeviceInfo;
import javax.media.Manager;
import javax.media.MediaLocator;
import javax.media.Player;
import javax.media.cdm.CaptureDeviceManager;
import javax.media.control.FrameGrabbingControl;
import javax.media.format.VideoFormat;
import javax.media.util.BufferToImage;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.border.TitledBorder;
import javax.swing.event.InternalFrameEvent;
import javax.swing.event.InternalFrameListener;

import org.apache.log4j.Logger;

import pfc.utils.CompressUtils;
import pfc.view.control.GeraMenuAplicacao;
import pfc.view.model.Icons;
import pfc.view.view.components.view.ImagePanel;
import pfc.view.view.components.view.JFileChooserLastDirectoryAware;

import com.google.zxing.MonochromeBitmapSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.ReaderException;
import com.google.zxing.Result;
import com.google.zxing.client.j2se.BufferedImageMonochromeBitmapSource;

public class TelaDecodificar extends JInternalFrame {

	private static final Logger logger = Logger
			.getLogger(TelaDecodificar.class); // @jve:decl-index=0:

	private static final String MSG_DECODIFICANDO = "Decodificando...";
	private static final String MSG_INICIO = "Aguardando início da decodificação"; 

	private JPanel jContentPane = null;

	private JInternalFrame bigThis = this;

	private JPanel jPanelCamera = null;

	private JPanel jPanelResultado = null;

	private JPanel jPanelStatus = null;

	private JLabel jLabelDadosReais = null;

	private JTextArea jTextArea = null;

	private JScrollPane jScrollPaneDadosReais = null;

	private JTextArea jTextAreaDadosReais = null;

	private JLabel jLabelStatus = null;

	private Component cameraComponent = null;

	private JButton jButton = null;

	private JButton jButtonParar = null;

	private JButton jButton1 = null;

	private Player player = null;

	private Thread threadDecodificar = null;

	private Buffer buf = null;

	private Image img = null;

	private BufferToImage btoi = null;

	private JButton jButtonDecodificarFoto = null;

	private JFileChooserLastDirectoryAware janelaAbrir;

	private ImagePanel imagePanel;  //  @jve:decl-index=0:

	private JPanel jPanelCameraInterna = null;

	/**
	 * This is the xxx default constructor
	 */
	public TelaDecodificar() {
		super();
		initialize();

		logger.info("Tela de Decodificar inicializada");
	}

	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {
		this.setSize(740, 740);
		this.setContentPane(getJContentPane());
		this.setResizable(true);
		this.setMaximizable(true);
		this.setIconifiable(true);
		this.setClosable(true);
		this.setFrameIcon(Icons.ICONEVALE);
		setTitle("Decodificar");
		getJButtonParar().setEnabled(false);
		this.addInternalFrameListener(new ListenerTela());
	}

	/**
	 * This method initializes jContentPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJContentPane() {
		if (jContentPane == null) {
			GridBagConstraints gridBagConstraints3 = new GridBagConstraints();
			gridBagConstraints3.gridx = 0;
			gridBagConstraints3.weightx = 1.0;
			gridBagConstraints3.weighty = 1.0;
			gridBagConstraints3.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints3.insets = new Insets(7, 7, 7, 7);
			gridBagConstraints3.gridy = 1;
			GridBagConstraints gridBagConstraints2 = new GridBagConstraints();
			gridBagConstraints2.gridx = 0;
			gridBagConstraints2.weightx = 1.0;
			gridBagConstraints2.weighty = 1.0;
			gridBagConstraints2.fill = GridBagConstraints.BOTH;
			gridBagConstraints2.insets = new Insets(7, 7, 7, 7);
			gridBagConstraints2.gridy = 2;
			GridBagConstraints gridBagConstraints = new GridBagConstraints();
			gridBagConstraints.gridx = 0;
			gridBagConstraints.insets = new Insets(7, 7, 7, 7);
			gridBagConstraints.fill = GridBagConstraints.BOTH;
			gridBagConstraints.weightx = 1.0;
			gridBagConstraints.weighty = 1.0;
			gridBagConstraints.gridy = 0;
			jContentPane = new JPanel();
			jContentPane.setLayout(new GridBagLayout());
			jContentPane.add(getJPanelCamera(), gridBagConstraints);
			jContentPane.add(getJPanelResultado(), gridBagConstraints2);
			jContentPane.add(getJPanelStatus(), gridBagConstraints3);
		}
		return jContentPane;
	}

	private class ListenerTela implements InternalFrameListener {

		public void internalFrameActivated(InternalFrameEvent e) {

		}

		public void internalFrameClosed(InternalFrameEvent e) {
			// TODO Auto-generated method stub
		}

		public void internalFrameClosing(InternalFrameEvent e) {
			GeraMenuAplicacao.getInstance().removeAplicacoesAbertas(bigThis);
			if (player != null) {
				player.close();
			}
		}

		public void internalFrameDeactivated(InternalFrameEvent e) {
			// TODO Auto-generated method stub
		}

		public void internalFrameDeiconified(InternalFrameEvent e) {
			// TODO Auto-generated method stub
		}

		public void internalFrameIconified(InternalFrameEvent e) {
			// TODO Auto-generated method stub
		}

		public void internalFrameOpened(InternalFrameEvent e) {

		}
	}
	
	private ImagePanel getImagePanel() {
		if (imagePanel == null) {
			imagePanel = new ImagePanel();
			imagePanel.setLayout(new GridBagLayout());
			imagePanel.setPreferredSize(new Dimension(320, 240));
//			imagePanel.setMinimumSize(new Dimension(320, 240));
		}
		return imagePanel;
	}

	/**
	 * This method initializes jPanelCamera
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJPanelCamera() {
		if (jPanelCamera == null) {
			GridBagConstraints gridBagConstraints12 = new GridBagConstraints();
			gridBagConstraints12.gridx = 2;
			gridBagConstraints12.insets = new Insets(7, 7, 7, 7);
			gridBagConstraints12.gridy = 1;
			GridBagConstraints gridBagConstraints11 = new GridBagConstraints();
			gridBagConstraints11.gridx = 3;
			gridBagConstraints11.insets = new Insets(7, 7, 7, 7);
			gridBagConstraints11.anchor = GridBagConstraints.EAST;
			gridBagConstraints11.gridy = 1;
			GridBagConstraints gridBagConstraints10 = new GridBagConstraints();
			gridBagConstraints10.gridx = 1;
			gridBagConstraints10.insets = new Insets(7, 7, 7, 7);
			gridBagConstraints10.anchor = GridBagConstraints.EAST;
			gridBagConstraints10.gridy = 1;
			GridBagConstraints gridBagConstraints9 = new GridBagConstraints();
			gridBagConstraints9.gridx = 0;
			gridBagConstraints9.insets = new Insets(7, 7, 7, 7);
			gridBagConstraints9.anchor = GridBagConstraints.EAST;
			gridBagConstraints9.gridy = 1;
			jPanelCamera = new JPanel();
			jPanelCamera.setLayout(new GridBagLayout());
			jPanelCamera.setBorder(BorderFactory.createTitledBorder(
					BorderFactory.createLineBorder(Color.blue, 1),
					"Decodificação", TitledBorder.DEFAULT_JUSTIFICATION,
					TitledBorder.DEFAULT_POSITION, new Font("Dialog",
							Font.BOLD, 12), new Color(51, 51, 51)));

			
			GridBagConstraints gridBagConstraints15 = new GridBagConstraints();
			gridBagConstraints15.anchor = GridBagConstraints.NORTHEAST;
			gridBagConstraints15.gridx = 0;
			gridBagConstraints15.insets = new Insets(7, 7, 7, 7);
			gridBagConstraints15.fill = GridBagConstraints.BOTH;
			gridBagConstraints15.weighty = 1.0;
			gridBagConstraints15.weightx = 1.0;
			gridBagConstraints15.gridwidth = 2;
			gridBagConstraints15.gridy = 0;
			
			GridBagConstraints gridBagConstraints16 = new GridBagConstraints();
			gridBagConstraints16.gridx = 2;
			gridBagConstraints16.insets = new Insets(7, 7, 7, 7);
			gridBagConstraints15.anchor = GridBagConstraints.NORTHWEST;
			gridBagConstraints16.fill = GridBagConstraints.BOTH;
			gridBagConstraints16.weighty = 1.0;
			gridBagConstraints16.weightx = 1.0;
			gridBagConstraints16.gridwidth = 2;
			gridBagConstraints16.gridy = 0;
			jPanelCamera.add(getJButton(), gridBagConstraints9);
			jPanelCamera.add(getJButtonParar(), gridBagConstraints10);
			jPanelCamera.add(getJButton1(), gridBagConstraints11);
			jPanelCamera.add(getJButtonDecodificarFoto(), gridBagConstraints12);
			jPanelCamera.add(getJPanelCameraInterna(), gridBagConstraints15);
			jPanelCamera.add(getImagePanel(), gridBagConstraints16);
		}
		return jPanelCamera;
	}

	private Component getCameraComponent() {
		if (cameraComponent == null) {

			Vector dispositivosLista = CaptureDeviceManager.getDeviceList(null);  
			Vector dataSourceList = Manager.getDataSourceList(null);
			
			String str2 = "vfw//0";
			CaptureDeviceInfo di = CaptureDeviceManager.getDevice(str2);
			MediaLocator ml = new MediaLocator("vfw://0");
//			MediaLocator ml = new MediaLocator("Unknown device/Unknown OS/Mobiola S60 3rd Ed");

			try {
				player = Manager.createRealizedPlayer(ml);
//				player = Manager.createRealizedPlayer((DataSource)dataSourceList.get(0));
				player.start();
				cameraComponent = player.getVisualComponent();
				
				if (cameraComponent == null) {
					throw new RuntimeException(
							"Não foi possível acessar a câmera");
				}
				cameraComponent.setPreferredSize(new Dimension(320, 240));
				cameraComponent.setMinimumSize(new Dimension(320, 240));
//				cameraComponent.setMaximumSize(new Dimension(400, 400));
//				cameraComponent.setPreferredSize(new Dimension(400, 400));
			} catch (Exception e) {
				e.printStackTrace();
				cameraComponent = new JPanel();
			}
		}
		return cameraComponent;
	}

	/**
	 * This method initializes jPanelResultado
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJPanelResultado() {
		if (jPanelResultado == null) {
			GridBagConstraints gridBagConstraints7 = new GridBagConstraints();
			gridBagConstraints7.fill = GridBagConstraints.BOTH;
			gridBagConstraints7.gridx = 0;
			gridBagConstraints7.gridy = 3;
			gridBagConstraints7.weightx = 1.0;
			gridBagConstraints7.weighty = 1.0;
			gridBagConstraints7.insets = new Insets(7, 7, 7, 7);
			GridBagConstraints gridBagConstraints6 = new GridBagConstraints();
			gridBagConstraints6.fill = GridBagConstraints.BOTH;
			gridBagConstraints6.gridy = 3;
			gridBagConstraints6.weightx = 1.0;
			gridBagConstraints6.weighty = 1.0;
			gridBagConstraints6.gridx = 0;
			GridBagConstraints gridBagConstraints5 = new GridBagConstraints();
			gridBagConstraints5.gridx = 0;
			gridBagConstraints5.insets = new Insets(7, 7, 7, 7);
			gridBagConstraints5.anchor = GridBagConstraints.WEST;
			gridBagConstraints5.gridy = 2;
			jLabelDadosReais = new JLabel();
			jLabelDadosReais.setText("Dados reais:");
			jPanelResultado = new JPanel();
			jPanelResultado.setLayout(new GridBagLayout());
			jPanelResultado.setBorder(BorderFactory.createTitledBorder(
					BorderFactory.createLineBorder(Color.blue, 1), "Resultado",
					TitledBorder.DEFAULT_JUSTIFICATION,
					TitledBorder.DEFAULT_POSITION, new Font("Dialog",
							Font.BOLD, 12), new Color(51, 51, 51)));
			jPanelResultado.add(jLabelDadosReais, gridBagConstraints5);
			jPanelResultado
					.add(getJScrollPaneDadosReais(), gridBagConstraints7);
		}
		return jPanelResultado;
	}

	/**
	 * This method initializes jPanelStatus
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJPanelStatus() {
		if (jPanelStatus == null) {
			GridBagConstraints gridBagConstraints8 = new GridBagConstraints();
			gridBagConstraints8.gridx = 0;
			gridBagConstraints8.insets = new Insets(7, 7, 7, 7);
			gridBagConstraints8.gridy = 0;
			jLabelStatus = new JLabel();
			jLabelStatus.setText(MSG_INICIO);
			jPanelStatus = new JPanel();
			jPanelStatus.setLayout(new GridBagLayout());
			jPanelStatus.setBorder(BorderFactory.createTitledBorder(
					BorderFactory.createLineBorder(Color.blue, 1),
					"Status da decodificação",
					TitledBorder.DEFAULT_JUSTIFICATION,
					TitledBorder.DEFAULT_POSITION, new Font("Dialog",
							Font.BOLD, 12), new Color(51, 51, 51)));
			jPanelStatus.add(jLabelStatus, gridBagConstraints8);
		}
		return jPanelStatus;
	}

	/**
	 * This method initializes jScrollPaneDadosReais
	 * 
	 * @return javax.swing.JScrollPane
	 */
	private JScrollPane getJScrollPaneDadosReais() {
		if (jScrollPaneDadosReais == null) {
			jScrollPaneDadosReais = new JScrollPane();
			jScrollPaneDadosReais.setViewportView(getJTextAreaDadosReais());
			jScrollPaneDadosReais.setPreferredSize(new Dimension(300, 60));
			jScrollPaneDadosReais.setMinimumSize(new Dimension(300, 60));
		}
		return jScrollPaneDadosReais;
	}

	/**
	 * This method initializes jTextAreaDadosReais
	 * 
	 * @return javax.swing.JTextArea
	 */
	private JTextArea getJTextAreaDadosReais() {
		if (jTextAreaDadosReais == null) {
			jTextAreaDadosReais = new JTextArea();
			jTextAreaDadosReais = new JTextArea();
			jTextAreaDadosReais.setEditable(false);
			jTextAreaDadosReais.setLineWrap(true);
			jTextAreaDadosReais.setText("");
			jTextAreaDadosReais.setFont(new Font("Courier New", Font.PLAIN, 12));
		}
		return jTextAreaDadosReais;
	}

	/**
	 * This method initializes jButton
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getJButton() {
		if (jButton == null) {
			jButton = new JButton(Icons.CONSULTAR);
			jButton.setText("Iniciar Decodificação");
			jButton.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					threadDecodificar = new Thread(new Runnable() {

						public void run() {
							while (true) {
								FrameGrabbingControl fgc = (FrameGrabbingControl) player
										.getControl("javax.media.control.FrameGrabbingControl");
								buf = fgc.grabFrame();
								btoi = new BufferToImage((VideoFormat) buf
										.getFormat());
								img = btoi.createImage(buf);

								try {
									File file = gravaImg(img);
									if (file != null) {
										byte[] compressedBytes = null;
										String decodeString = getDecodeText(file, compressedBytes);
										String s = "Decodificação realizada com sucesso!";
										getImagePanel().setImage(ImageIO.read(file.getAbsoluteFile()));
										getJTextAreaDadosReais().setText(decodeString);
										JOptionPane.showMessageDialog(null, s);
										getJButton().setEnabled(true);
										getJButtonDecodificarFoto().setEnabled(true);
										getJButtonParar().setEnabled(false);
										jLabelStatus.setText(MSG_INICIO);
										
										break;
									}
								} catch (ReaderException exception) {

								} catch (IOException exception) {
									exception.printStackTrace();
								}
							}

						}

						private File gravaImg(Image imagem) {
							String tempdir = System
									.getProperty("java.io.tmpdir");

							if (!(tempdir.endsWith("/") || tempdir
									.endsWith("\\")))
								tempdir = tempdir
										+ System.getProperty("file.separator");

							String caminho = tempdir + "teste" + ".PNG";
							try {
								File imgFile = new File(caminho);
								ImageIO.write((RenderedImage) imagem, "png",
										imgFile);
								// JOptionPane.showMessageDialog(this,
								// "Imagem Capturada!");
								return imgFile;
							} catch (IOException e) {
								JOptionPane
										.showMessageDialog(
												null,
												"n�o foi possivel encontrar "
														+ "o dispositivo para a captura da imagem.");
								e.printStackTrace();
								return null;
							}

						}

					});
					getJButton().setEnabled(false);
					getJButtonDecodificarFoto().setEnabled(false);
					getJButtonParar().setEnabled(true);
					jLabelStatus.setText(MSG_DECODIFICANDO);
					threadDecodificar.start();
				}
			});
		}
		return jButton;
	}
	
	private String getDecodeText(File file, byte[] compressedBytes)
			throws ReaderException {
		BufferedImage image;
		try {
			image = ImageIO.read(file);
		} catch (IOException ioe) {
			return ioe.toString();
		}
		if (image == null) {
			return "Could not decode image";
		}
		MonochromeBitmapSource source = new BufferedImageMonochromeBitmapSource(image);
		Result result;
		try {
			result = new MultiFormatReader().decode(source);
		} catch (ReaderException re) {
			throw re;
		}
		// System.out.println(result.getRawBytes());
		Vector compressedBytesVector = result.getByteSegments();
		if (compressedBytesVector != null) {
			compressedBytes = (byte[]) (compressedBytesVector.get(0));
			byte[] decompressedBytes = CompressUtils
					.decompress(compressedBytes);

			String resultStr = "";
			for (int i = 0; i < decompressedBytes.length; i++) {
				if (decompressedBytes[i] == 0x0A)
					resultStr += "-";
				else
					resultStr += decompressedBytes[i];
			}
			return resultStr;
		} else {
//			return result.getText();
			throw ReaderException.getInstance();
		}
	}

	/**
	 * This method initializes jButtonParar
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getJButtonParar() {
		if (jButtonParar == null) {
			jButtonParar = new JButton(Icons.PARAR);
			jButtonParar.setText("Parar Decodificação");
			jButtonParar.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					if (threadDecodificar != null) {
						threadDecodificar.stop();
						getJButton().setEnabled(true);
						getJButtonDecodificarFoto().setEnabled(true);
						getJButtonParar().setEnabled(false);
						jLabelStatus.setText(MSG_INICIO);
					}
				}
			});
		}
		return jButtonParar;
	}

	/**
	 * This method initializes jButton1
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getJButton1() {
		if (jButton1 == null) {
			jButton1 = new JButton(Icons.FECHAR);
			jButton1.setText("Fechar");
			jButton1.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					bigThis.setVisible(false);
					GeraMenuAplicacao.getInstance().removeAplicacoesAbertas(
							bigThis);
				}
			});
		}
		return jButton1;
	}

	/**
	 * This method initializes jButtonDecodificarFoto	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getJButtonDecodificarFoto() {
		if (jButtonDecodificarFoto == null) {
			jButtonDecodificarFoto = new JButton(Icons.PASTA);
			jButtonDecodificarFoto.setText("Decodificar Foto");
			
			janelaAbrir = new JFileChooserLastDirectoryAware("DecodificarFoto");
			janelaAbrir.setDialogTitle("Abrir arquivo XLS");
			janelaAbrir.setPreferredSize(new Dimension(580,360));
			janelaAbrir.setAcceptAllFileFilterUsed(false);
//			janelaAbrir.addChoosableFileFilter(new BmpFilter());
			janelaAbrir.setMultiSelectionEnabled(false);
			jButtonDecodificarFoto.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					int opcao = janelaAbrir.showOpenDialog(TelaDecodificar.this);
					janelaAbrir.setLastDirectory(janelaAbrir.getCurrentDirectory());
					if(opcao == janelaAbrir.APPROVE_OPTION){
						File file = janelaAbrir.getSelectedFile();
						if (file != null) {
							try {
								byte[] compressedBytes = null;
								String decodeString = getDecodeText(file, compressedBytes);
								String s = "Decodificação realizada com sucesso!";
								getImagePanel().setImage(ImageIO.read(file.getAbsoluteFile()));
								getJTextAreaDadosReais().setText(decodeString);
								JOptionPane.showMessageDialog(null, s);
								getJButton().setEnabled(true);
								getJButtonParar().setEnabled(false);
								jLabelStatus.setText(MSG_INICIO);
								
							} catch (ReaderException exception) {
								JOptionPane.showMessageDialog(null, "Não foi possível decodificar.");
							} catch (RuntimeException exception) {
								JOptionPane.showMessageDialog(null, exception.getMessage());
							} catch (IOException exception) {
								exception.printStackTrace();
							}
						}
					}
				}
			});
		}
		return jButtonDecodificarFoto;
	}
	
	public class BmpFilter extends javax.swing.filechooser.FileFilter {

		public boolean accept(File file) {
			String fileName = file.getName().toLowerCase();
			return fileName.toLowerCase().endsWith(".bmp")
					|| file.isDirectory();
		}

		public String getDescription() {
			return "Arquivos *.bmp";
		}
		
	}

	/**
	 * This method initializes jPanelCameraInterna	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getJPanelCameraInterna() {
		if (jPanelCameraInterna == null) {
			GridBagConstraints gridBagConstraints13 = new GridBagConstraints();
			gridBagConstraints13.anchor = GridBagConstraints.NORTHEAST;
			gridBagConstraints13.fill = GridBagConstraints.BOTH;
			gridBagConstraints13.gridwidth = 1;
			gridBagConstraints13.gridx = 0;
			gridBagConstraints13.gridy = 0;
			gridBagConstraints13.weightx = 1.0;
			gridBagConstraints13.weighty = 1.0;
			gridBagConstraints13.insets = new Insets(0, 0, 0, 0);
			jPanelCameraInterna = new JPanel();
			jPanelCameraInterna.setLayout(new GridBagLayout());
			jPanelCameraInterna.add(getCameraComponent(), gridBagConstraints13);
			jPanelCameraInterna.setPreferredSize(new Dimension(320, 240));
			jPanelCameraInterna.setMinimumSize(new Dimension(320, 240));
		}
		return jPanelCameraInterna;
	}

} // @jve:decl-index=0:visual-constraint="10,10"
